package cn.juque.jdfsystem.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.juque.common.constants.StringConstants;
import cn.juque.common.constants.YesOrNoEnum;
import cn.juque.common.disruptor.DisruptorHandler;
import cn.juque.jdfsystem.cache.FileInfoCache;
import cn.juque.jdfsystem.disruptor.bo.SendMsgBodyBO;
import cn.juque.jdfsystem.disruptor.event.SendMsgDisruptorEventServiceImpl;
import cn.juque.jdfsystem.domain.FileInfoDO;
import cn.juque.jdfsystem.enums.HttpMessageTypeEnum;
import cn.juque.jdfsystem.helper.FileInfoHelper;
import cn.juque.jdfsystem.mapper.FileInfoMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author juque
 * @version 1.0.0
 * <ul>
 *     <li>ClearInValidFileTask</li>
 * </ul>
 * @date 2023-01-18 10:41:47
 **/
@Service("clearInValidFileTask")
public class ClearInValidFileTask extends AbstractTask{

    @Resource
    private FileInfoMapper fileInfoMapper;

    @Resource
    private FileInfoHelper fileInfoHelper;

    @Resource
    private FileInfoCache fileInfoCache;

    @Resource
    private DisruptorHandler disruptorHandler;

    /**
     * 任务逻辑
     *
     * @param args 参数
     */
    @Override
    public void execute(String[] args) {
        if(ArrayUtil.isEmpty(args) && Boolean.TRUE.equals(checkExecuteNode())) {
            List<String> pathList = this.clearDbFile();
            this.clearDiskFile(pathList);
            if(CollUtil.isEmpty(pathList)) {
                return;
            }
            SendMsgBodyBO<List<String>> bodyBO = new SendMsgBodyBO<>();
            bodyBO.setMessageTypeEnum(HttpMessageTypeEnum.FILE_DEL);
            bodyBO.setPayload(pathList);
            bodyBO.setBusinessEventService(SendMsgDisruptorEventServiceImpl.BEAN);
            this.disruptorHandler.publish(bodyBO);
            return ;
        }
        this.clearDiskFile(CollUtil.newArrayList(args));
    }

    /**
     * 设置随机休眠等待最大时长 单位：秒
     *
     * @return 秒
     */
    @Override
    protected Integer initSleepTimes() {
        return null;
    }

    private List<String> clearDbFile() {
        if(Boolean.FALSE.equals(super.checkExecuteNode())) {
            return CollUtil.newArrayList();
        }
        // 默认清除7天前无效的文件
        Date date = DateUtil.offsetDay(new Date(), -7);
        FileInfoDO query = new FileInfoDO();
        query.setCreateDateEnd(DateUtil.format(date, DatePattern.PURE_DATE_PATTERN));
        query.setValidFlag(YesOrNoEnum.NO.getCode());
        List<FileInfoDO> list = this.fileInfoMapper.queryInfoList(query);
        List<String> absolutePathList = list.stream().map(m->{
            File file = this.fileInfoHelper.getFile(m);
            return FileUtil.getAbsolutePath(file);
        }).collect(Collectors.toList());
        // 清理
        list.parallelStream().forEach(f->this.fileInfoHelper.deleteInfo(f));
        return absolutePathList;
    }

    /**
     * 清理文件
     * @param absolutePathList 文件的绝对路径列表
     */
    private void clearDiskFile(List<String> absolutePathList) {
        if(CollUtil.isEmpty(absolutePathList)) {
            return;
        }
        absolutePathList.parallelStream().forEach(f->{
            File file = FileUtil.file(f);
            String fileName = file.getName();
            // 清理本地文件
            FileUtil.del(f);
            // 清理缓存
            String fileId = CharSequenceUtil.subBefore(fileName, StringConstants.POINT, true);
            this.fileInfoCache.delete(fileId);
        });
    }

    @Override
    protected String getTaskName() {
        return "ClearInValidFileTask";
    }
}
